package tjs.study.notes.queue.consumeA.kafka;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.annotation.KafkaListenerAnnotationBeanPostProcessor;
import org.springframework.stereotype.Service;
import tjs.study.notes.queue.consumeA.kafka.initial.InitialKafkaConsumer;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

/**
 * Created by Nicky.Tang on 2023/5/15 下午3:03
 *
 * @since 02.12.10
 */
@Service
public class 非注解实现 implements InitializingBean {
    @Autowired
    private KafkaListenerAnnotationBeanPostProcessor kafkaListenerAnnotationBeanPostProcessor;
    @Autowired
    private InitialKafkaConsumer initialKafkaConsumer;


    @Override
    public void afterPropertiesSet() throws Exception {
        Method registerMethod = KafkaListenerAnnotationBeanPostProcessor.class.getDeclaredMethod("processKafkaListener",
                KafkaListener.class, Method.class, Object.class, String.class);
        registerMethod.setAccessible(true);
        Method method = InitialKafkaConsumer.class.getMethod("receiveMessage", String.class);
        method.setAccessible(true);
        
        KafkaListener kafkaListener = method.getAnnotation(KafkaListener.class);
        //获取 foo 这个代理实例所持有的 InvocationHandler
        InvocationHandler invocationHandler = Proxy.getInvocationHandler(kafkaListener);
        // 获取 AnnotationInvocationHandler 的 memberValues 字段
        Field declaredField = invocationHandler.getClass().getDeclaredField("memberValues");
        // 因为这个字段事 private final 修饰，所以要打开权限
        declaredField.setAccessible(true);
        // 获取 memberValues
        Map memberValues = (Map) declaredField.get(invocationHandler);
        // 修改 value 属性值
        memberValues.put("groupId", "test.annotation.new.value");
        
        Object bean = initialKafkaConsumer;
        String beanName = "initialKafkaConsumer";
        registerMethod.invoke(kafkaListenerAnnotationBeanPostProcessor, kafkaListener, method,bean,beanName);
        //kafkaListenerAnnotationBeanPostProcessor.processKafkaListener();
    }

    public static void main(String[] args) throws Exception {
        //updateAnnotion();

    }
    
    


    private static void updateAnnotion() throws Exception {
        Method method = InitialKafkaConsumer.class.getMethod("receiveMessage", String.class);
        KafkaListener kafkaListener = method.getAnnotation(KafkaListener.class);
        System.out.println("修改之前的注解值：" + kafkaListener.groupId());
        //获取 foo 这个代理实例所持有的 InvocationHandler
        InvocationHandler invocationHandler = Proxy.getInvocationHandler(kafkaListener);
        // 获取 AnnotationInvocationHandler 的 memberValues 字段
        Field declaredField = invocationHandler.getClass().getDeclaredField("memberValues");
        // 因为这个字段事 private final 修饰，所以要打开权限
        declaredField.setAccessible(true);
        // 获取 memberValues
        Map memberValues = (Map) declaredField.get(invocationHandler);
        // 修改 value 属性值
        memberValues.put("groupId", "test.annotation.new.value");
        // 获取 foo 的 value 属性值
        String newValue = kafkaListener.groupId();
        System.out.println("修改之后的注解值：" + newValue);
        CosumeItem aa = initOne("aaaa");
        aa.init();
        System.out.println("aa1:" + aa.receiveMessage(""));
        CosumeItem bb = initOne("bbb");
        bb.init();
        System.out.println("bb1:" + bb.receiveMessage(""));
        System.out.println("aa2:" + aa.receiveMessage(""));
        System.out.println("bb2:" + bb.receiveMessage(""));
    }

    private static CosumeItem initOne(String aa) {
        return new CosumeItem() {
            @Override
            public void init() throws Exception {
                Method method = this.getClass().getMethod("receiveMessage", String.class);
                KafkaListener kafkaListener = method.getAnnotation(KafkaListener.class);
                System.out.println(aa + "修改之前的注解值：" + kafkaListener.groupId());
                //获取 foo 这个代理实例所持有的 InvocationHandler
                InvocationHandler invocationHandler = Proxy.getInvocationHandler(kafkaListener);
                // 获取 AnnotationInvocationHandler 的 memberValues 字段
                Field declaredField = invocationHandler.getClass().getDeclaredField("memberValues");
                // 因为这个字段事 private final 修饰，所以要打开权限
                declaredField.setAccessible(true);
                // 获取 memberValues
                Map memberValues = (Map) declaredField.get(invocationHandler);
                // 修改 value 属性值
                memberValues.put("groupId", aa);
                // 获取 foo 的 value 属性值
                String newValue = kafkaListener.groupId();
                System.out.println(aa + "修改之后的注解值：" + newValue);
            }

            @Override
            @KafkaListener(groupId = "testGroup3", topics = {"tjs_test_cousumer6"}/*, concurrency = "1"*/)
            public String receiveMessage(String message) throws Exception {
                Method method = this.getClass().getMethod("receiveMessage", String.class);
                KafkaListener kafkaListener = method.getAnnotation(KafkaListener.class);
                return kafkaListener.groupId();
            }
        };
    }


    public interface CosumeItem {

        void init() throws Exception;

        String receiveMessage(String message) throws Exception;
    }


}
